﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Xml.Serialization;
using XEvents.Library.Targets;
using System.ComponentModel;

namespace XEvents.Library
{
    /// <summary>
    /// EventSessionTarget object
    /// </summary>
    [Serializable]
    public class EventSessionTarget
    {
        public EventSessionTarget()
        { }

        internal EventSessionTarget(server_event_session_target sest, EventSession ses)
        {
            this.parent = ses;
            this.name = sest.package + "." + sest.name;
            this.options = new EventSessionTargetOptionCollection(from sesf in ses.Server.sessiondata.server_event_session_fields
                                                                  where sesf.event_session_id == sest.event_session_id
                                                                  && sesf.object_id == sest.target_id
                                                                  select new EventSessionTargetOption(sesf));
        }

        internal EventSession parent;
        private string name = string.Empty;
        private EventSessionTargetOptionCollection options = new EventSessionTargetOptionCollection();

        [XmlIgnore, BrowsableAttribute(false)]
        public EventSession Parent
        {
            get { return parent; }
        }


        [XmlIgnore, BrowsableAttribute(false)]
        public TargetData TargetData
        {
            get
            {
                if (parent.SessionState == SessionState.Stop)
                    return null;
                else 
                    return TargetDataFactory.GetTargetData(this);
            }
        }

        /// <summary>
        /// Determines whether the EventSessionTarget is equal to the current EventSessionTarget
        /// </summary>
        /// <param name="obj">EventSessionTarget to be compared to</param>
        public override bool Equals(object obj)
        {
            EventSessionTarget t = (EventSessionTarget)obj;
            if (t == null)
                return false;
            else
            {
                if (t.options.Count != options.Count)
                    return false;
                foreach (EventSessionTargetOption to in t.options)
                {
                    if (!options.Contains(to))
                        return false;
                }

                if (t.name != name)
                    return false;

                return true;
            }
        }

        /// <summary>
        /// Returns the hash code for this EventSessionTarget
        /// </summary>
        public override int GetHashCode()
        {
            return name.GetHashCode() ^ options.GetHashCode();
        }

        /// <summary>
        /// EventSessionTarget Name
        /// </summary>
        [XmlAttribute("Name")]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        /// <summary>
        /// Returns the Options string for this EventSessionTarget
        /// </summary>
        [XmlAttribute("OptionsString")]
        public string OptionsString
        {
            get
            {
                string retval = string.Empty;
                foreach (EventSessionTargetOption sto in options)
                {
                    retval += sto.ScriptOption() + ", ";
                }
                if (retval.EndsWith(", "))
                    retval = retval.Substring(0, retval.Length - 2);

                return retval;
            }
        }

        /// <summary>
        /// Returns the SessionTargetOptions collection for this EventSessionTarget
        /// </summary>
        public EventSessionTargetOptionCollection Options
        {
            get { return options; }
        }

        /// <summary>
        /// Adds a EventSessionTargetOption to this EventSessionTarget
        /// /// </summary>
        /// <param name="option">EventSessionTargetOption to Add</param>
        public bool AddTargetOption(EventSessionTargetOption option)
        {
            if (!(this.options.Contains(option)))
            {
                this.options.Add(option);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Removes a EventSessionTargetOption from this EventSessionTarget
        /// /// </summary>
        /// <param name="option">EventSessionTargetOption to remove from this EventSessionTarget</param>
        public bool RemoveTargetOption(EventSessionTargetOption option)
        {
            if (this.options.Contains(option))
            {
                this.options.Remove(option);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Returns the Options string for this EventSessionTarget
        /// DEPRECATED and will be removed from future versions
        /// </summary>
        public string GetOptionsString()
        {
            string retval = string.Empty;
            foreach (EventSessionTargetOption sto in options)
            {
                retval += sto.ScriptOption() + ", ";
            }
            if (retval.EndsWith(", "))
                retval = retval.Substring(0, retval.Length - 2);

            return retval;
        }

        /// <summary>
        /// Returns the ADD TARGET script component for this EventSessionTarget
        /// </summary>
        public string Script()
        {
            string retval = string.Format(@"ADD TARGET {0}(", name);

            if (options.Count > 0)
            {
                retval += "\r\n" + string.Format("     SET {0}", GetOptionsString());
            }

            if (retval.EndsWith("("))
                return retval.Substring(0, retval.Length - 1) + ",";
            else
                return retval + "),";
        }

        /// <summary>
        /// Returns the DROP TARGET script component for this EventSessionTarget
        /// </summary>
        public string ScriptDrop()
        {
            return string.Format(@"DROP TARGET {0},", name);
        }

    }
}
